#include <iostream>
#include <vector>
#include <algorithm>
#include <numeric>
#include <cmath>

/// <summary>
/// һ�� ��������ϴ�ͱ�׼������ʾ����
/// </summary>
struct SensorData {
    double value;
    bool isValid() const { return !std::isnan(value) && value >= 0; }
};

void dataCleaningDemo() {
    std::vector<SensorData> readings = {
        {15.2}, {NAN}, {-3.5}, {28.7}, {0.0}, {NAN}, {42.1}
    };

    // �Ƴ���Ч����
    readings.erase(
        std::remove_if(readings.begin(), readings.end(),
            [](const SensorData& data) { return !data.isValid(); }),
        readings.end()
    );

    // ����Ƿ�����Ч����
    if (readings.empty()) {
        std::cout << "No valid data remaining after cleaning.\n";
        return;
    }

    //c++14���ݴ���
    auto minmax = std::minmax_element(
        readings.begin(), readings.end(),
        [](const SensorData& a, const SensorData& b) { return a.value < b.value; }
    );
    double minVal = minmax.first->value;//ָ����СԪ�ء�//-> �ǵ������Ľ����ò����������ڷ��� SensorData ����ĳ�Ա��
    double maxVal = minmax.second->value;//ָ�����Ԫ��
    //c++17 ����
    //double minVal = minmax.first->value;
    //double maxVal = minmax.second->value;
    //// ��׼�����ݵ�[0,1]��Χ
    //auto [minIt, maxIt] = std::minmax_element(
    //    readings.begin(), readings.end(),
    //    [](const SensorData& a, const SensorData& b) { return a.value < b.value; }
    //);

    //double minVal = minIt->value;
    //double maxVal = maxIt->value;

    // ��ֹ�����㣨������ֵ��ͬʱ��
    if (maxVal == minVal) {
        std::transform(readings.begin(), readings.end(), readings.begin(),
            [](SensorData data) {
                data.value = 0.5; // ����ֵ��Ϊ��ֵ
                return data;
            });
    }
    else {
		// ��׼�����ݵ�[0,1]��Χ
        std::transform(readings.begin(), readings.end(), readings.begin(),
            [=](SensorData data) {
                data.value = (data.value - minVal) / (maxVal - minVal);
                return data;
            });
    }

    // ��ӡ���
    std::cout << "Cleaned and normalized data:\n";
    for (const auto& data : readings) {
        std::cout << data.value << " ";
    }
    std::cout << "\n\n";
}

int main() {
    dataCleaningDemo();
    return 0;
}